import { HttpStatus, Injectable } from '@nestjs/common';
import { CreateUserAccountDto } from './dto/create-user_account.dto';
import { UpdateUserAccountDto } from './dto/update-user_account.dto';
import { UpdateUserInfo } from './dto/edit-userInfo.dto'
import { UserAccount } from './entities/user_account.entity';
import { UserHobby } from './entities/user_hobby.entity';
import { Article } from 'src/article/entities/article.entity';
import { Announcement } from './entities/announcement.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

@Injectable()
export class UserAccountService {
  constructor(@InjectRepository(UserAccount) private readonly userAccount: Repository<UserAccount>,
    @InjectRepository(UserHobby) private readonly userHobby: Repository<UserHobby>,
    @InjectRepository(Article) private readonly article: Repository<Article>,
    @InjectRepository(Announcement) private readonly announcement: Repository<Announcement>,
  ) {
  }
  //创建一个账户
  async create(createUserAccountDto: CreateUserAccountDto) {
    //账户已存在
    const userCounts = await this.userAccount.find({ where: { account: createUserAccountDto.account } })
    if (userCounts.length != 0) return { code: HttpStatus.BAD_REQUEST, msg: '账户已存在' }

    const userAccount = new UserAccount()
    userAccount.account = createUserAccountDto.account
    userAccount.password = createUserAccountDto.password
    await this.userAccount.save(userAccount)
    return {
      code: HttpStatus.OK,
      msg: '注册成功',
    }

  }

  //查看所有账户
  async findAll() {
    try {
      const queryBuilder = this.userAccount.createQueryBuilder('userAccount')
        .leftJoinAndSelect('userAccount.hobbies', 'hobbies')
        .leftJoinAndSelect('userAccount.follower', 'follower')
        .leftJoinAndSelect('userAccount.followings', 'followings')
        .select(['userAccount', 'hobbies', 'follower', 'followings'])
        .orderBy('userAccount.root', 'DESC')
      const data = await queryBuilder.getMany()
      const total = await queryBuilder.getCount()
      return {
        code: HttpStatus.OK,
        msg: '查询成功',
        data,
        total
      }
    } catch (error) {
      return {
        code: HttpStatus.BAD_REQUEST,
        msg: '查询失败'
      }
    }

  }

  //登录
  async login(accountDto: { account: string, password: string }) {
    const account = await this.userAccount.findOne({ where: { account: accountDto.account } })
    if (!account) return { code: HttpStatus.NOT_FOUND, msg: '用户不存在' }
    if (account.banned) {
      return {
        code: HttpStatus.FORBIDDEN,
        msg: '账号已被封禁'
      }
    }
    if (account.password === accountDto.password) {
      //如果查到 且密码相等
      return {
        code: HttpStatus.OK,
        msg: '登录成功',
        data: account
      }
    } else {
      return {
        code: HttpStatus.NOT_FOUND,
        msg: '登录失败,请重试'
      }
    }
  }

  //通过uuid更新账户
  async update(updateUserAccountDto: UpdateUserAccountDto) {
    const userAccount = await this.userAccount.findOne({
      where: { uuid: updateUserAccountDto.uuid, account: updateUserAccountDto.account }
    })
    if (!userAccount) {
      return {
        code: HttpStatus.NOT_FOUND,
        msg: '数据匹配错误'
      }
    } else if (userAccount.password !== updateUserAccountDto.oldPassword) {
      return {
        msg: '密码错误',
        code: HttpStatus.BAD_REQUEST
      }
    } else {
      userAccount.password = updateUserAccountDto.newPassword
      const data = await this.userAccount.save(userAccount)
      return {
        code: HttpStatus.OK,
        msg: '修改成功',
        data
      }
    }
  }

  //听过uuid查找用户
  async findOneByUUID(uuidDto: { uuid: string }) {
    // const data = await this.userAccount.findOne({ where: { uuid: uuidDto.uuid }, relations: ['hobbies','likes','commentLikes','follower','followings'] })

    const data = await this.userAccount.createQueryBuilder('userAccount')
      .leftJoinAndSelect('userAccount.hobbies', 'hobbies')
      .leftJoinAndSelect('userAccount.likes', 'articleLikes')
      .leftJoinAndSelect('userAccount.commentLikes', 'commentLikes')
      .leftJoinAndSelect('commentLikes.article', 'commentLikeArticle')
      .leftJoinAndSelect('articleLikes.liker', 'liker')
      .leftJoinAndSelect('userAccount.follower', 'follower')
      .leftJoinAndSelect('userAccount.followings', 'followings')
      .where('userAccount.uuid=:uuid', { uuid: uuidDto.uuid })
      .select(['userAccount.uuid', 'userAccount.avatar', 'userAccount.id', 'userAccount.nickname', 'userAccount.root', 'userAccount.gender', 'userAccount.birthday', 'userAccount.email', 'userAccount.phone', 'userAccount.address', 'userAccount.introduction', 'userAccount.profession', 'articleLikes', 'commentLikes', 'hobbies', 'liker', 'commentLikeArticle.id', 'followings.uuid', 'followings.avatar', 'followings.nickname', 'follower.uuid', 'follower.avatar', 'follower.nickname'])
      .getOne()

    if (data) {
      return {
        code: HttpStatus.OK,
        msg: '查询成功',
        data
      }
    } else {
      return {
        code: HttpStatus.NOT_FOUND,
        msg: '查询失败,请重试'
      }
    }
  }

  //通过uuid删除一个用户
  async remove(uuid: string) {
    //先找到用户
    try {
      const account = await this.userAccount.findOne({ where: { uuid }, relations: ['hobbies', 'articles', 'collections', 'likes'] })
      if (!account) return { code: HttpStatus.NOT_FOUND, msg: '未找到用户' }
      //先移除爱好
      if (account.hobbies) {
        account.hobbies.forEach(async (hobby) => {
          await this.userHobby.remove(hobby)
        })
      }
      const data = await this.userAccount.remove(account)
      return {
        code: HttpStatus.OK,
        msg: '删除成功',
        data
      }
    } catch (error) {
      return {
        code: HttpStatus.BAD_REQUEST,
        msg: '删除失败'
      }
    }
  }

  //通过UUID更新个人信息
  async updateUserInfo(updateUserInfoDto: UpdateUserInfo) {
    //先获取需要修改的行
    const userAccount = await this.userAccount.findOne({ where: { uuid: updateUserInfoDto.uuid }, relations: ['hobbies'] })
    console.log(updateUserInfoDto);

    Object.keys(updateUserInfoDto).forEach(item => {
      return item !== 'uuid' && item !== 'hobbies' && (userAccount[item] = updateUserInfoDto[item])
    })



    try {
      // 存在爱好修改
      if (updateUserInfoDto.hobbies) {
        //移除先前爱好
        await this.userHobby.remove(userAccount.hobbies)
        let hobbies: Array<UserHobby> = []
        //循环遍历爱好 
        for (let i = 0; i < updateUserInfoDto.hobbies.length; i++) {
          const hobby = new UserHobby()
          hobby.name = updateUserInfoDto.hobbies[i]
          //保存爱好
          await this.userHobby.save(hobby)
          hobbies.push(hobby)
        }
        userAccount.hobbies = hobbies
      }


      const data = await this.userAccount.save(userAccount)

      return {
        data,
        msg: '修改成功',
        code: HttpStatus.OK
      }
    } catch (error) {
      return {
        msg: '修改失败',
        code: HttpStatus.BAD_REQUEST,
        xxx: userAccount,
        error
      }
    }
  }


  /**
  **@description：收藏文章
  **/
  async articleCollect(articleCollectDto: { uuid: string, articleId: number }) {
    const userAccount = await this.userAccount.findOne({ where: { uuid: articleCollectDto.uuid }, relations: ['collections'] })
    const article = await this.article.findOne({ where: { id: articleCollectDto.articleId }, relations: ['beCollected'] })
    //未找到
    if (!article || !userAccount)
      return {
        msg: '未找到',
        code: HttpStatus.NOT_FOUND
      }
    //先判定是否已经收藏
    const hasArticle = userAccount.collections.findIndex(item => item.id === articleCollectDto.articleId)
    if (hasArticle !== -1) {
      //存在把之前的取消掉
      userAccount.collections.splice(hasArticle, 1)
    } else {
      userAccount.collections.push(article)
    }
    const hasCollected = hasArticle === -1 ? true : false
    try {
      await this.userAccount.save(userAccount)
      return {
        msg: hasCollected ? '已收藏' : '已取消收藏',
        code: HttpStatus.OK,
        data: article,
        hasCollected
      }
    } catch (error) {
      return {
        msg: '网络异常',
        code: HttpStatus.BAD_REQUEST
      }
    }

  }

  /**
    **@description：uuid查询收藏文章 
    **/
  async findAllCollectedArticle(collectedArticleDto: { uuid: string, keyword?: string }) {
    const { uuid, keyword } = collectedArticleDto
    try {
      const queryBuilder = this.userAccount.createQueryBuilder('userAccount')
        .leftJoinAndSelect('userAccount.collections', 'article')
        .where('userAccount.uuid = :uuid', { uuid })
      if (collectedArticleDto.keyword) {
        queryBuilder.andWhere('article.title LIKE :keyword', { keyword: `%${keyword}%` })
      }
      const data = (await queryBuilder.getOne()).collections
      const total = data.length
      if (!data) {
        return {
          code: HttpStatus.BAD_REQUEST,
          msg: '格式错误'
        }
      }
      return {
        code: HttpStatus.OK,
        msg: '查询成功',
        total,
        data
      }
    } catch (error) {
      return {
        code: HttpStatus.BAD_REQUEST,
        msg: '查询失败'
      }
    }
  }

  /**
    **@description：点赞文章
    **/
  async supportArticle(supportArticleDto: { uuid: string, articleId: number }) {
    const userAccount = await this.userAccount.findOne({ where: { uuid: supportArticleDto.uuid }, relations: ['likes'] })
    const article = await this.article.findOne({ where: { id: supportArticleDto.articleId }, relations: ['liker'] })
    //未找到
    if (!article || !userAccount)
      return {
        msg: '未找到',
        code: HttpStatus.NOT_FOUND
      }
    //判断是否已点过赞
    const hasArticle = userAccount.likes.findIndex(item => item.id === supportArticleDto.articleId)
    if (hasArticle !== -1) {
      //清楚掉之前点过的
      userAccount.likes.splice(hasArticle, 1)
    } else {
      userAccount.likes.push(article)
    }

    const hasSupport = hasArticle === -1 ? true : false
    try {
      await this.userAccount.save(userAccount)
      return {
        code: HttpStatus.OK,
        msg: hasSupport ? '已点赞' : '已取消点赞',
        data: article,
        hasSupport
      }
    } catch (error) {
      return {
        msg: '网络异常',
        code: HttpStatus.BAD_REQUEST
      }
    }
  }

  /**
    **@description: 关注/取关
    **/
  async followUp(followDto: { uuid: string, follow_uuid: string }) {
    if (followDto.uuid == followDto.follow_uuid) return { code: HttpStatus.BAD_REQUEST, msg: '不能关注自己' }
    try {
      const userAccount = await this.userAccount.findOne({ where: { uuid: followDto.uuid }, relations: ['followings'] })
      const upAccount = await this.userAccount.findOne({ where: { uuid: followDto.follow_uuid }, relations: ['follower'] })
      if (!userAccount || !upAccount) return { code: HttpStatus.BAD_REQUEST, msg: '未找到用户' }
      const hasUpAccount = userAccount.followings.findIndex(item => item.uuid === upAccount.uuid)
      if (hasUpAccount === -1) {
        userAccount.followings.push(upAccount)
      } else {
        userAccount.followings.splice(hasUpAccount, 1)
      }
      const hasFollowed = hasUpAccount === -1 ? true : false
      const data = await this.userAccount.save(userAccount)

      return {
        code: HttpStatus.OK,
        msg: hasFollowed ? '已关注' : '取消关注',
        data
      }
    } catch (error) {
      return {
        code: HttpStatus.BAD_REQUEST,
        msg: '网络错误'
      }
    }

  }

  /** 
     **@description: 删除浏览记录 
     **/
  async delHistory(delHistoryDto: { uuid: string, articleId: number }) {
    try {
      const { uuid, articleId } = delHistoryDto
      const userAccount = await this.userAccount.findOne({ where: { uuid }, relations: ['views'] })
      const data = await this.article.findOneById(articleId)
      const hasArticle = userAccount.views.findIndex(item => item.id === articleId)

      if (hasArticle !== -1) {
        userAccount.views.splice(hasArticle, 1)
      }
      await this.userAccount.save(userAccount)
      return {
        code: HttpStatus.OK,
        msg: '删除成功',
        data
      }
    } catch (error) {
      return {
        code: HttpStatus.BAD_REQUEST,
        msg: '删除失败'
      }
    }
  }


  /**  
   **@description: 站长发布通知
   **/
  async publicAnnouncement(announcementDto: { id?: number, content: string, title: string }) {
    const { id, content, title } = announcementDto
    //查看是否需要修改
    if (id) {
      try {
        const announcement = await this.announcement.findOneById(id)
        if (!announcement) {
          return {
            code: HttpStatus.BAD_REQUEST,
            msg: '未找到'
          }
        }
        announcement.content = content
        announcement.title = title
        const data = await this.announcement.save(announcement)
        return {
          code: HttpStatus.OK,
          msg: '修改成功',
          data
        }
      } catch (error) {
        return {
          code: HttpStatus.BAD_REQUEST,
          msg: '修改失败'
        }
      }
    } else {
      //新增
      const announcement = new Announcement()
      announcement.content = content
      announcement.title = title
      try {
        await this.announcement.save(announcement)
        return {
          code: HttpStatus.OK,
          msg: '创建成功'
        }
      } catch (error) {
        return {
          code: HttpStatus.BAD_REQUEST,
          msg: '创建失败'
        }
      }
    }
  }

  async getAnnouncement() {
    try {
      const data = await this.announcement.find({ order: { createTime: "DESC" }, take: 3 })
      if (!data) {
        return {
          code: HttpStatus.BAD_REQUEST,
          msg: "查找异常"
        }
      }
      return {
        data,
        code: HttpStatus.OK,
        msg: '获取成功'
      }
    } catch (error) {
      return {
        code: HttpStatus.BAD_REQUEST,
        msg: "查找失败"
      }
    }
  }

} 
